<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of BUIBase
 *
 * @author ID59C
 */
abstract class BUIBase extends CComponent implements BUIObj {

    const BOOTSTRAPSTYLE = "bootstrap";
    const ContextVARIABLE_STRING = 'string';
    const ContextVARIABLE_SCOPETYPE = 'ScopeVariable';
    const LinkType_AjaxLink = "ajaxLink";
    const LinkType_AjaxButton = "ajaxButton";
    const LinkType_AjaxSubmitButton = "ajaxSubmitButton";
    const ajaxContainter_application = "b_show_blyn_content";
    const ajaxContainter_Space = "b_show_space_content";
    const ajaxContainter_App = "b_show_app_content";
    const ajaxContainer_operationFlow = "b_show_operation_flow_content";
    const ajaxContainter_operation = "b_show_operation_content";
    const ajaxContainter_screenFlow = "b_show_screenFlow_content";
    const ajaxContainter_screen = "b_show_screen_content";
    const ajax_startView_application = "appStartView";
    const ajax_startView_Space = "SpaceStartView";
    const ajax_startView_App = "AppStartView";
    const ajax_startView_operation = "operationStartView";
    const ajax_startView_screenFlow = "screenFlowStartView";
    const ajax_startView_screen = "screenStartView";

    protected $views = null;
    protected $ajaxViews = null;
    protected $layoutView = null;
    protected $count = 0;
    protected $containerView = null;
    protected $showLoadGif = '$("#ajax-loaderdiv").show();';

    public function __construct() {
        $this->onRegisterMenu = array($this, 'registerMenu');
    }

    /*
      public function getHomeUrl() {
      return $this->buildUrl('home');
      }
     * 
     */

    public function buildUrl($spaceId = null, $appId = null, $operationId = null, $data = null) {

        $params = array();

        if ($spaceId == 'index' || $spaceId == 'home') {
            return yii::app()->createUrl('site/index');
        }

        $bn = null;

        if ($spaceId != null) {
            //$spaceId = $space->getId();
            $spaceId = (($spaceId + 99) * 2 + 2) * 3;
            $bn = $spaceId;
        }

        if ($appId != null) {
            //$appId = $app->getId();
            $appId = (($appId + 99) * 3 + 2) * 2;
            $bn = $bn . "_" . $appId;
        }

        if ($operationId != null) {
            //$opId = $operation->getId();
            $opId = (($operationId + 99) * 2 + 2) * 3;
            $bn = $bn . "_" . $opId;
        }

        if ($bn != NULL)
            $params['bn'] = $bn;

        //rltp is roleType attached for Space in left menu
        /*
          if (isset($_REQUEST['rtp'])) {
          $params['rtp'] = $_REQUEST['rtp'];
          //    unset($_REQUEST['rtp']);
          }
         * 
         */

        if ($data != null) {
            foreach ($data as $key => $value) {
                if ($key != 'bn')
                    $params[$key] = $value;
            }
        }

        $url = array('site/index');

        if (!empty($params)) {
            foreach ($params as $key => $value) {
                $url[$key] = $value;
            }
        }

        return $url;
    }

    public function deUrl() {

        if (isset($_GET['bn'])) {

            $bnString = $_GET['bn'];

            $t = explode("#", $bnString);

            $url = trim($t[0], "_");

            $s = explode("_", $url);

            $config = array();

            if (isset($s[0])) {
                $sId = intval($s[0]);
                $config['spaceId'] = ($sId / 3 - 2) / 2 - 99;
            }

            if (isset($s[1])) {
                $aId = intval($s[1]);
                $config['appId'] = ($aId / 2 - 2) / 3 - 99;
            }

            if (isset($s[2])) {
                $oId = intval($s[2]);
                $config['OperationId'] = ($oId / 3 - 2) / 2 - 99;
            }

            return $config;
        }
    }

    //put your code here
    public function getFormByMeta($formName, $parentScreen = null, $config = NULL) {

        $form = null;
        $formMeta = null;
        $formModel = null;

        if ($config != NULL) {
            if (isset($config['meta']))
                $formMeta = $config['meta'];

            if (isset($config['model']))
                $formModel = $config['model'];
        }

        if ($formMeta == NULL)
            $formMeta = $this->getFormMeta($formName . 'FormMeta');

        if ($formModel == NULL) {
            $modelName = $formName . 'FormModel';
            $formModel = new $modelName;
        } else
            $formModel = new $formModel;

        $formModel->setScenario($formName);

        $form = new CForm($formMeta, $formModel);

        return $form;
    }

    protected function getFormMeta($name) {

        if (function_exists('lcfirst'))
            $lname = lcfirst($name);
        else
            $lname = strtolower(substr($name, 0, 1)) . substr($name, 1);


        if (!isset($this->$lname)) {
            $meta = require(Yii::getPathOfAlias(Blyn::app()->getCurrentNode()->getUIManager()->getUINodeFilesPath('formPath') . ".meta." . $name) . '.php');
        } else
            $meta = $this->$lname;

        return $meta;
    }

    public function getScreen($name) {

        if (!$this instanceof BUINode) {
            $uiNode = Blyn::app()->getCurrentNode()->getUIManager();
        } else {
            $uiNode = $this;
        }
        return $uiNode->getScreen($name);
    }

    /**
     * 
     */
    public function getScreenFlow($name) {
        if (!$this instanceof BUINode) {
            $uiNode = Blyn::app()->getCurrentNode()->getUIManager();
        } else {
            $uiNode = $this;
        }
        return $uiNode->getScreenFlow($name);
    }

    public function gotoScreen($screen, $data = array()) {

        if (is_string($screen))
            $screen = $this->getScreen($screen);

        if ($screen instanceof BUIScreen) {
            if (!$screen->isMemberOfScreenFlow()) {
                Blyn::app()->getCurrentNode()->getUIManager()->setCurrentScreen($screen);
            }

            Blyn::app()->getUIManager()->renderApp($data);
        }
    }

    public function gotoUINode($spaceId = NULL, $appId = NULL, $operationId = NULL, $data = array()) {
        //add by jianfeng in 3/3/2013
        //Blyn::app()->setContext();
        Blyn::app()->runApp(array('spaceId' => $spaceId, 'appId' => $appId, 'operationId' => $operationId));
    }

    public function gotoScreenFlow($name, $data = array()) {
        $scnFlow = $this->getScreenFlow($name);

        if ($scnFlow instanceof BUIScreenFlow)
            Blyn::app()->getCurrentNode()->getUIManager()->setCurrentScreenFlow($scnFlow);

        Blyn::app()->getUIManager()->renderApp($data);

        /*
          $flowIndex = $scnFlow->getContextVariable(BUIScreenFlow::ContextVARIABLE_SCREENFLOW_INDEX);
          if ($flowIndex == NULL) {
          $flowIndex = 0;
          }

          if (isset($_GET['screenFlowIndex'])) {
          $flowIndex = $_GET['screenFlowIndex'];
          }

          if (isset($data['index']))
          $flowIndex = $data['index'];

          $scnFlow->setIndex($flowIndex);

          // $scnFlow->render($data);
          //refine in 3/3/2013
          $currentUINode = Blyn::app()->getCurrentNode()->getUIManager();
          $currentUINode->setCurrentScreenFlow($scnFlow);
          $currentUINode->renderNode($data);
         * 
         */
    }

    //this function will render view according to id
    /**
     * sometime, javascript may trigger an ajax request for rendering required view
     * then can call this function directly render view
     * to make it work, first should add view into screen by using addRenderView
     * @param type $id
     * @param type $views
     * @param type $data
     */
    public function gotoView($ajaxLinkId, $views, $data = array()) {

        $aViews = array();

        if (is_string($views)) {
            array_push($aViews, array('view' => $views, 'data' => $data));
        }

        if (is_array($views))
            $aViews = $views;

        /**
         * some links just loading view in specific container, can createAjaxLink for the view
         */
        if (isset($_REQUEST['b_ajaxLinkId']) && $_REQUEST['b_ajaxLinkId'] == $ajaxLinkId) {
            foreach ($aViews as $item) {
                $view = $item['view'];
                $viewData = isset($item['data']) ? $item['data'] : NULL;
                $this->renderView($view, $viewData);
            }
        }

        Blyn::app()->getContextObj()->saveContextVariable();

        yii::app()->end();
    }

    /**
     *
     * @param type $style
     * @return BMenuBootStrap 
     */
    protected function getMenuManager($style = null) {
        if ($style == NULL)
            $style = BUIBlyn::BOOTSTRAPSTYLE;

        if ($style == BUIBlyn::BOOTSTRAPSTYLE) {
            if ($this->bootStrapMenu == null) {
                $this->bootStrapMenu = new BMenuBootStrap ();
                $this->menuManager = $this->bootStrapMenu;
            }

            return $this->bootStrapMenu;
        }
    }

    public function getMenu($name, $style = null) {

        if ($style == NULL)
            $style = BUIBlyn::BOOTSTRAPSTYLE;

        $menuManager = Blyn::app()->getAppUI()->getMenuManager();

        $menu = $menuManager->getMenu($name);

        if ($menu == NULL)
            $menu = yii::app()->cache->get('menu_' . $name);

        if ($menu == NULL) {
            $event = new CEvent($this);
            $this->onRegisterMenu($event);
            $menu = $menuManager->getMenu($name);
//by default, cache menu for 30 seconds
            yii::app()->cache->set('menu_' . $name, $menu, 30);
        }

        return $menu;
    }

    public function addMenuItem(&$menu, $menuItem, $style = NULL) {
        $menuManager = $this->getMenuManager($style);
        $menuManager->addMenuItem($menu, $menuItem);
    }

    public function addMenu($name, $menu, $style = NULL) {
        $menuManager = $this->getMenuManager($style);
        $menuManager->addMenu($name, $menu);
    }

    public function onRegisterMenu($event) {
        $this->raiseEvent('onRegisterMenu', $event);
    }

    public function renderView($view, $data = NULL, $uiNode = NULL) {

        $currentNode = Blyn::app()->getCurrentNode();
        $uiNode = $currentNode->getUIManager();
        $viewPath = NULL;
        $filePath = NULL;
        $beginRender = FALSE;

        //first find path from control viewPath
        if ($this instanceof BUIControl && $this->getViewPath() != NULL) {
            $viewPath = $this->getViewPath();
            $rViewPath = $this->getRelativeViewPath();
            if ($viewPath != NULL && is_dir(yii::getPathOfAlias($viewPath))) {
                //first find from template folder
                $template = $this->getViewTemplate();
                if ($template != NULL) {
                    $viewFile = $viewPath . '.' . $template . '.' . $view;
                    if (file_exists(yii::getPathOfAlias($viewFile) . '.php')) {
                        $beginRender = TRUE;
                    }
                }
                //if not find in template, find from control view path
                if (!$beginRender) {
                    $viewFile = $viewPath . '.' . $view;
                    if (file_exists(yii::getPathOfAlias($viewFile) . '.php')) {
                        $beginRender = TRUE;
                    }
                }
            }
        }

        //then find view from activeApp
        if (!$beginRender) {
            $rView = $view;
            if (isset($rViewPath) && is_string($rViewPath) && $rViewPath != NULL) {
                $rView = $rViewPath . '.' . $view;
            }
            $template = $this->getViewTemplate();
            if ($template != NULL) {
                $rView = $template . '.' . $view;
            }
            $viewPath = Blyn::app()->getActiveApp()->getUIManager()->getViewPath($rView);
            if ($viewPath != NULL && file_exists(yii::getPathOfAlias($viewPath) . '.php')) {
                $viewFile = $viewPath;
                //if (file_exists(yii::getPathOfAlias($viewFile) . '.php')) {
                $beginRender = TRUE;
                //}
            }
            //find in views of app folder
            if ($beginRender == FALSE) {
                $viewPath = Blyn::app()->getActiveApp()->getUIManager()->getViewPath($view);
                if ($viewPath != NULL && file_exists(yii::getPathOfAlias($viewPath) . '.php')) {
                    $viewFile = $viewPath;
                    //if (file_exists(yii::getPathOfAlias($viewFile) . '.php')) {
                    $beginRender = TRUE;
                    //}
                }
            }
        }

        //final find from blyn app 
        if (!$beginRender) {
            $viewPath = Blyn::app()->getUIManager()->getViewPath();
            if ($viewPath != NULL && is_dir(yii::getPathOfAlias($viewPath))) {
                $template = $this->getViewTemplate();
                if ($template != NULL) {
                    $tViewPath = $viewPath . '.' . $template . '.' . $view;
                    if (file_exists(yii::getPathOfAlias($tViewPath) . '.php')) {
                        $beginRender = TRUE;
                        $viewFile = $tViewPath;
                    }
                }
                if (!$beginRender) {
                    $viewFile = $viewPath . '.' . $view;
                    if (file_exists(yii::getPathOfAlias($viewFile) . '.php')) {
                        $beginRender = TRUE;
                    }
                }
            }
        }

        if ($beginRender) {
            $controller = Yii::app()->getController();
            $controller->renderPartial($viewFile, $data);
            return;
        }

        /*
          if ($viewPath == NULL || !is_dir(yii::getPathOfAlias($viewPath))) {
          $viewPath = Blyn::app()->getActiveApp()->getUIManager()->getViewPath();
          }

          //default view for control
          if (!$currentNode instanceof BSpace || $currentNode instanceof BlynApp)
          $viewPath = Blyn::app()->getActiveApp()->getUIManager()->getViewPath($view);

          if (!$uiNode instanceof BUIBlyn && $uiNode instanceof BUIControl && $uiNode->getViewPath() != NULL)
          $viewPath = $uiNode->getViewPath();

          if ($this instanceof BUIControl && $this->getViewPath() != NULL)
          $viewPath = $this->getViewPath();

          //    $viewPath = $uiNode->viewPath;

          if (!is_array($data))
          $data = array();

          if (!is_dir(yii::getPathOfAlias($viewPath)))
          $viewPath = Blyn::app()->getAppUI()->getViewPath();

          if ($this instanceof BUIControl) {
          if ($this->getViewTemplate() != NULL) {
          $templateViewPath.=$viewPath . '.' . $this->getViewTemplate();
          if (is_dir(yii::getPathOfAlias($templateViewPath))) {
          $viewPath = $templateViewPath;
          }
          }
          }

          $viewFile = $viewPath . '.' . $view;

          if (!file_exists(yii::getPathOfAlias($viewFile) . '.php')) {
          $viewFile = $viewPath = Blyn::app()->getActiveApp()->getViewPath() . '.' . $view;
          } else if (!file_exists(yii::getPathOfAlias($viewFile) . '.php')) {
          $viewFile = $viewPath = Blyn::app()->getAppUI()->getViewPath() . '.' . $view;
          } else {
          $viewFile = $viewFile;
          }

          $controller = Yii::app()->getController();
          $controller->renderPartial($viewFile, $data);
          //        $controller->renderPartial('blankLayout', array('view' => $view, 'data' => $data));
         * 
         */
    }

    /*
      public function renderLayout($layout) {
      $this->renderView($layout->getLayoutView(), $layout->getLayoutData());
      }
     * 
     */

    public function addRenderView($name, $viewName, $viewData = NULL) {
        if ($viewData == NULL)
            $viewData = array('uiObj' => $this);
        if ($this->views == NULL)
            $this->views = array();
        $this->views[$name] = array('view' => $viewName, 'data' => $viewData);
    }

    public function setRenderView($name, $viewName, $viewData = NULL) {
        if (isset($this->views[$name]) && $viewName != NULL)
            $this->views[$name] = array('view' => $viewName, 'data' => $viewData);
    }

    public function removeRenderView($name) {
        if (isset($this->views[$name]))
            unset($this->views[$name]);
    }

    public function addAjaxRenderView($id, $viewName, $viewData = NULL) {
        $views = array();
        $ajaxLinkId = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getId() . "_" . $id;
        if ($viewData == NULL)
            $viewData = array('uiObj' => $this);
        if ($this->ajaxViews == NULL)
            $this->ajaxViews = array();
        array_push($views, array('ajaxView' => $viewName, 'data' => $viewData));
        $this->ajaxViews[$ajaxLinkId] = $views;
    }

    public function getViews() {
        if ($this->views == NULL)
            $this->views = array();

        return $this->views;
    }

    public function getAjaxViews() {
        if ($this->ajaxViews == NULL)
            $this->ajaxViews = array();

        return $this->ajaxViews;
    }

    /**
     * 
     * @param type $id
     * @param type $name, name to show in link
     * @param type mix, format:string or array('ajaxView'=>'name of view','data'=>'data of view')
     * @param type $url
     * @param type $ajaxOption
     * @param type $htmlOption
     * @return type
     */
    public function buildAjaxLink($id, $name = null, $url = null, $ajaxViews = null, $ajaxOptions = array(), $htmlOptions = array()) {

        $ajaxLinkId = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getId() . "_" . $id;

        if (yii::app()->getRequest()->isAjaxRequest) {
            $ajaxLinkId = 'j_' . $ajaxLinkId;
        }

//prepare views
        $ajaxViewName = NULL;
        $aViews = array();

        if (is_string($ajaxViews)) {
            $ajaxViewName = $ajaxViews;
            array_push($aViews, array('ajaxView' => $ajaxViewName));
        }

        if (is_array($ajaxViews))
            $aViews = $ajaxViews;

//if not specify any view for link, use startPage as view for show screen
//meanwhile need to set up ajaxOption to update bilyn_start_page div
        if ($aViews == NULL) {
            array_push($aViews, array('ajaxView' => 'startPage'));
            $ajaxOptions['update'] = '#bilyn_start_page';
        }

//add ajaxView into session variable, that will use before start render
        $ajaxRenderViews = Blyn::app()->getCurrentNode()->getUIManager()->getContextVariable('bilyn_ajaxViews');

        if ($ajaxRenderViews == NULL)
            $ajaxRenderViews = array();

        $ajaxRenderViews[$ajaxLinkId] = $aViews;

        Blyn::app()->getCurrentNode()->getUIManager()->addContextVariable('bilyn_ajaxViews', $ajaxRenderViews);
        Blyn::app()->getContextObj()->saveContextVariable();

//prepare url
        if ($url == NULL) {
            $url = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getUrl();
        }
//put ajaxLinkId into url 
        $url['bilyn_ajaxLink'] = $ajaxLinkId;

        if ($name == NULL) {
            $name = $id;
        }

        $ajaxOptions['replace'] = TRUE;

        $request = yii::app()->getRequest();

        if ($request->isAjaxRequest) {
            if (!isset($ajaxOptions['type']))
                $ajaxOptions['type'] = 'POST';
            if (!isset($ajaxOptions['url']))
                $ajaxOptions['url'] = $url;
            /*
              if (isset($htmlOptions['submit'])) {
              $cs->registerCoreScript('yii');
              $request = Yii::app()->getRequest();
              if ($request->enableCsrfValidation && isset($htmlOptions['csrf']) && $htmlOptions['csrf'])
              $htmlOptions['params'][$request->csrfTokenName] = $request->getCsrfToken();
              if (isset($htmlOptions['params']))
              $params = CJavaScript::encode($htmlOptions['params']);
              else
              $params = '{}';
              if ($htmlOptions['submit'] !== '')
              $url = CJavaScript::quote(self::normalizeUrl($htmlOptions['submit']));
              else
              $url = '';
              $handler.="jQuery.yii.submitForm(this,'$url',$params);{$return};";
              }
             * 
             */
//   if(isset($htmlOptions['submit'])){
//      $ajaxOptions['data']='js:jQuery(this).parents("form").serialize()';
//  }
            $ajaxScript = CHtml::ajax($ajaxOptions);
            $htmlOptions['onclick'] = $ajaxScript . 'return false;';
            $htmlOptions['id'] = blyn::app()->getCurrentNode()->getUIManager()->getUniqueControlId();
            $ajaxLink = CHtml::link($name, '#', $htmlOptions);
//$ajaxlink = CHtml::ajaxLink($name, $url, $ajaxOptions, $htmlOptions);
            return $ajaxLink;
        }

        if (!isset($ajaxOptions['type']))
            $ajaxOptions['type'] = 'POST';

        $ajaxLink = CHtml::ajaxLink($name, $url, $ajaxOptions, $htmlOptions);

        return $ajaxLink;
    }

    /**
     * this function is use to create ajax link in site, by default, ajaxLink will only refresh current screen    
     * @param type $name the name if ajaxLink, use as label of ajaxLink
     * @param type $ajaxContainerId, the target id where ajax content is update or replace
     * @param type $addingView, the view will be loaded into target holder
     * @param type $data, usually contain ajaxOptions and url data, formate like $data = array('ajaxOptions'=>array(...),'urlOptions'=>array('url'=>'...','data'=>array())
     */
    public function createAjaxLink($idOrName, $url = NULL, $ajaxContainerId = null, $ajaxView = null, $data = NULL) {

        $name = 'Undefined Link';
        $id = 'undefined_link_' . Blyn::app()->getUnicodeId();
        $getData = NULL;
        $addingView = null;
        $addingViewData = NULL;

        if (is_string($ajaxView))
            $addingView = $ajaxView;

        if (is_array($ajaxView)) {
            $addingView = isset($ajaxView['view']) ? $ajaxView['view'] : NULL;
            $addingViewData = isset($ajaxView['data']) ? $ajaxView['data'] : NULL;
        }


        if (is_string($idOrName) || is_numeric($idOrName)) {
            $id = str_replace(" ", "_", $idOrName);
            $name = $idOrName;
        }
        if (is_array($idOrName)) {
            if (isset($idOrName['id']))
                $id = $idOrName['id'];
            if (isset($idOrName['label']))
                $name = $idOrName['label'];
            if (isset($idOrName['name']))
                $name = $idOrName['name'];
        }

//by default, set screen as with Space operation container        
        if ($url == NULL) {
            $currentScreen = Blyn::app()->getUIManager()->getCurrentScreen();
            $url = $currentScreen->getUrl();
            $ajaxContainerId = self::ajaxContainter_operation;
            //$ajaxContainerId = Blyn::app()->getActiveOperation()->getUIManager()->getContainerView();
            $addingView = Blyn::app()->getActiveOperation()->getUIManager()->getLayoutView();
        }

//by default, ajax container set to Space
        if ($ajaxContainerId == NULL || $ajaxView == NULL) {
            $ajaxContainerId = self::ajaxContainter_Space;
            //$ajaxContainerId = Blyn::app()->getActiveSpace()->getUIManager()->getContainerView();
            $addingView = Blyn::app()->getActiveSpace()->getUIManager()->getLayoutView();
        }

//replace all space with "_" and add node id to get ajaxLinkId
        $ajaxLinkId = isset($data['ajaxLinkId']) ? $data['ajaxLinkId'] : $addingView . "_" . $id;

        if (isset($data['ajaxLinkId']))
            unset($data['ajaxLinkId']);

//$postData = isset($data['data']) ? $data['data'] : array();
        $htmlOptions = isset($data['htmlOptions']) ? $data['htmlOptions'] : array();

        $ajaxLinkId = md5($ajaxLinkId);

        if (isset($data['data'])) {
            $getData = $data['data'];
        }

        if (is_array($data)) {
            if (isset($data['ajaxLinkId']))
                unset($data['ajaxLinkId']);
            if (isset($data['htmlOptions']))
                unset($data['htmlOptions']);
            foreach ($data as $key => $value) {
                if (is_string($value) || is_numeric($value) || $value == NULL)
                    $url[$key] = $value; //add data into get 
                else if ($value != NULL) {//add data as session variable
                    $postData = array();
                    $postData[$key] = $value;
                }
            }
        }

        //add data into url for passing by GetData
        if (is_array($getData) && $getData != NULL) {
            foreach ($getData as $key => $value) {
                if (is_string($value) || is_numeric($value) || $value == NULL)
                    $url[$key] = $value; //add data into get 
                else if ($value != NULL) {//add data as session variable
                    $postData = array();
                    $postData[$key] = $value;
                }
            }
        }

        if (is_array($url)) {
            $url['b_ajaxLinkId'] = $ajaxLinkId;
            $route = $url[0];
            unset($url[0]);
            $params = $url;
            $url = yii::app()->getController()->createUrl($route, $params);
        } else if (is_string($url)) {
            $route = $url;
            $url = yii::app()->getController()->createUrl($route, array('b_ajaxLinkId' => $ajaxLinkId));
        }

        $currentAjaxViews = Blyn::app()->getCurrentUser()->getContextVariable('currentAjaxViews');
        if ($currentAjaxViews == NULL)
            $currentAjaxViews = array();

        $currentAjaxViews[$ajaxLinkId] = array('view' => $addingView, 'data' => $addingViewData);

        Blyn::app()->getCurrentUser()->addContextVariable('currentAjaxViews', $currentAjaxViews);

        $ajaxOptions = isset($data['ajaxOptions']) ? $data['ajaxOptions'] : array();
        $ajaxOptions['type'] = 'POST';
        $ajaxOptions['url'] = $url;
        $ajaxOptions['update'] = '#' . $ajaxContainerId;
        //$ajaxOptions['replace'] = '#' . $ajaxContainerId;
        $ajaxOptions['replace'] = TRUE;
        if (isset($postData) && $postData != NULL)
            $ajaxOptions['data'] = $postData;

        if (!isset($ajaxOptions['beforeSend'])) {
            $ajaxOptions['beforeSend'] = 'function(){' . $this->showLoadGif . '}';
        }

        if (!isset($ajaxOptions['complete'])) {
            $ajaxOptions['complete'] = 'function(){$("#ajax-loaderdiv").hide();}';
        }


        if (yii::app()->getRequest()->isAjaxRequest) {
            if (!isset($ajaxOptions['type']))
                $ajaxOptions['type'] = 'POST';
            if (!isset($ajaxOptions['url']))
                $ajaxOptions['url'] = $url;
//$ajaxOptions['replace'] = TRUE;
            $ajaxScript = CHtml::ajax($ajaxOptions);
            $htmlOptions['onclick'] = $ajaxScript . ' return false;';
//$htmlOptions['id'] = blyn::app()->getCurrentNode()->getUIManager()->getUniqueControlId();
            $ajaxLink = CHtml::link($name, '#', $htmlOptions);
//$ajaxlink = CHtml::ajaxLink($name, $url, $ajaxOptions, $htmlOptions);
            return $ajaxLink;
        }

        $ajaxLink = CHtml::ajaxLink($name, $url, $ajaxOptions, $htmlOptions);

        return $ajaxLink;
    }

    public function createAjaxScript($idOrName, $url = NULL, $ajaxContainerId = null, $ajaxView = null, $data = NULL) {
        $name = 'Undefined Link';
        $id = 'undefined_link_' . Blyn::app()->getUnicodeId();
        $getData = NULL;
        $addingView = null;
        $addingViewData = NULL;

        if (is_string($ajaxView))
            $addingView = $ajaxView;

        if (is_array($ajaxView)) {
            $addingView = isset($ajaxView['view']) ? $ajaxView['view'] : NULL;
            $addingViewData = isset($ajaxView['data']) ? $ajaxView['data'] : NULL;
        }


        if (is_string($idOrName) || is_numeric($idOrName)) {
            $id = str_replace(" ", "_", $idOrName);
            $name = $idOrName;
        }
        if (is_array($idOrName)) {
            if (isset($idOrName['id']))
                $id = $idOrName['id'];
            if (isset($idOrName['label']))
                $name = $idOrName['label'];
            if (isset($idOrName['name']))
                $name = $idOrName['name'];
        }

//by default, set screen as with Space operation container        
        if ($url == NULL) {
            $currentScreen = Blyn::app()->getUIManager()->getCurrentScreen();
            $url = $currentScreen->getUrl();
            $ajaxContainerId = self::ajaxContainter_operation;
            //$ajaxContainerId = Blyn::app()->getActiveOperation()->getUIManager()->getContainerView();
            $addingView = Blyn::app()->getActiveOperation()->getUIManager()->getLayoutView();
        }

//by default, ajax container set to Space
        if ($ajaxContainerId == NULL || $ajaxView == NULL) {
            $ajaxContainerId = self::ajaxContainter_Space;
            //$ajaxContainerId = Blyn::app()->getActiveSpace()->getUIManager()->getContainerView();
            $addingView = Blyn::app()->getActiveSpace()->getUIManager()->getLayoutView();
        }



//replace all space with "_" and add node id to get ajaxLinkId
        $ajaxLinkId = isset($data['ajaxLinkId']) ? $data['ajaxLinkId'] : $addingView . "_" . $id;

        if (isset($data['ajaxLinkId']))
            unset($data['ajaxLinkId']);

//$postData = isset($data['data']) ? $data['data'] : array();
        $htmlOptions = isset($data['htmlOptions']) ? $data['htmlOptions'] : array();

        $ajaxLinkId = md5($ajaxLinkId);

        if (isset($data['data'])) {
            $getData = $data['data'];
        }

        if (is_array($data)) {
            if (isset($data['ajaxLinkId']))
                unset($data['ajaxLinkId']);
            if (isset($data['htmlOptions']))
                unset($data['htmlOptions']);
            foreach ($data as $key => $value) {
                if (is_string($value) || is_numeric($value) || $value == NULL)
                    $url[$key] = $value; //add data into get 
                else if ($value != NULL) {//add data as session variable
                    $postData = array();
                    $postData[$key] = $value;
                }
            }
        }

        //add data into url for passing by GetData
        if (is_array($getData) && $getData != NULL) {
            foreach ($getData as $key => $value) {
                if (is_string($value) || is_numeric($value) || $value == NULL)
                    $url[$key] = $value; //add data into get 
                else if ($value != NULL) {//add data as session variable
                    $postData = array();
                    $postData[$key] = $value;
                }
            }
        }

        if (is_array($url)) {
            $url['b_ajaxLinkId'] = $ajaxLinkId;
            $route = $url[0];
            unset($url[0]);
            $params = $url;
            $url = yii::app()->getController()->createUrl($route, $params);
        } else if (is_string($url)) {
            $route = $url;
            $url = yii::app()->getController()->createUrl($route, array('b_ajaxLinkId' => $ajaxLinkId));
        }

        $currentAjaxViews = Blyn::app()->getCurrentUser()->getContextVariable('currentAjaxViews');
        if ($currentAjaxViews == NULL)
            $currentAjaxViews = array();

        $currentAjaxViews[$ajaxLinkId] = array('view' => $addingView, 'data' => $addingViewData);

        Blyn::app()->getCurrentUser()->addContextVariable('currentAjaxViews', $currentAjaxViews);

        $ajaxOptions = isset($data['ajaxOptions']) ? $data['ajaxOptions'] : array();
        $ajaxOptions['type'] = 'POST';
        $ajaxOptions['url'] = $url;
        $ajaxOptions['update'] = '#' . $ajaxContainerId;
        //$ajaxOptions['replace'] = '#' . $ajaxContainerId;
        $ajaxOptions['replace'] = TRUE;
        if (isset($postData) && $postData != NULL)
            $ajaxOptions['data'] = $postData;

        if (!isset($ajaxOptions['beforeSend'])) {
            //$ajaxOptions['beforeSend'] = 'function(){'. $this->showLoadGif . '}';
            $ajaxOptions['beforeSend'] = 'function(){$("#ajax-loaderdiv").show();}';
        }

        if (!isset($ajaxOptions['complete'])) {
            $ajaxOptions['complete'] = 'function(){$("#ajax-loaderdiv").hide();}';
        }

        if (!isset($ajaxOptions['type']))
            $ajaxOptions['type'] = 'POST';
        if (!isset($ajaxOptions['url']))
            $ajaxOptions['url'] = $url;
        $ajaxScript = CHtml::ajax($ajaxOptions);
        return CHtml::encode($ajaxScript . ' return false;');
    }

    public function getAjaxLink($name, $data = NULL, $sender = NULL) {
        $ajaxContainer = isset($data['ajaxContainer']) ? $data['ajaxContainer'] : BUIBase::ajaxContainter_Space;
        $ajaxView = isset($data['ajaxView']) ? $data['ajaxView'] : Blyn::app()->getActiveSpace()->getUIManager()->getLayoutView();
        return $this->createAjaxLink($name, $this->getUrl(), $ajaxContainer, $ajaxView, $data);
    }

    /**
     * when create own ajax link by user sucess function, use this function to register views for ajaxLine
     * @param type $id
     * @param type $ajaxViews
     */
    public function registerAjaxLinkViews($id, $ajaxViews) {
        $this->buildAjaxLink($id, NULL, NULL, $ajaxViews);
        $ajaxLinkId = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getId() . "_" . $id;
        return $ajaxLinkId;
    }

    public function getAjaxLinkId($id, $ajaxView = NULL) {
        $view = is_null($ajaxView) ? Blyn::app()->getActiveSpace()->getUIManager()->getLayoutView() : $ajaxView;
        $ajaxLinkId = $view . "_" . $id;
        return $ajaxLinkId;
    }

    public function isLinkClicked($id) {
        $id = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getId() . "_" . $id;

        if (isset($_GET[$id]) || isset($_POST[$id]))
            return TRUE;

        return FALSE;
    }

    public function isAjaxLinkClicked($name, $containerView = NULL) {

        if ($containerView == NULL)
            $containerView = Blyn::app()->getActiveSpace()->getUIManager()->getLayoutView();
//$ajaxLinkId = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getId() . "_" . $id;
        $ajaxLinkId = $containerView . "_" . str_replace(" ", "_", $name);

        if (isset($_REQUEST['b_ajaxLinkId']) && ($_REQUEST['b_ajaxLinkId'] === $ajaxLinkId))
            return TRUE;

        return FALSE;
    }

    public function buildAjaxScript($id, $ajaxViews = null, $url = null, $ajaxOption = NULL) {
        $ajaxLinkId = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getId() . "_" . $id;

//prepare views
        $ajaxViewName = NULL;
        $aViews = array();

        if (is_string($ajaxViews)) {
            $ajaxViewName = $ajaxViews;
            array_push($aViews, array('ajaxView' => $ajaxViewName));
        }

        if (is_array($ajaxViews))
            $aViews = $ajaxViews;

//add ajaxView into session variable, that will use before real render
        $ajaxViews = Blyn::app()->getCurrentNode()->getUIManager()->getContextVariable('bilyn_ajaxViews');

        if ($ajaxViews == NULL)
            $ajaxViews = array();

        $ajaxViews[$ajaxLinkId] = $aViews;
        Blyn::app()->getCurrentNode()->getUIManager()->addContextVariable('bilyn_ajaxViews', $ajaxViews);
        Blyn::app()->getContextObj()->saveContextVariable();

//prepare url
        if ($url == NULL) {
            $url = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getUrl();
        }
        $url['bilyn_ajaxLink'] = $ajaxLinkId;

        if (!is_array($ajaxOption))
            $ajaxOption = array();

        $ajaxOption['url'] = $url;

        return CHtml::ajax($ajaxOption);
    }

    public function buildLink($id, $label = NULL, $type = NULL, $url = NULL, $data = array(), $htmlOptions = array()) {

        $ajaxOptions = array();

        if ($type == "ajaxLink") {
            if ($data != NULL)
                $ajaxOptions['data'] = $data;
            $name = $label == NULL ? $id : $label;
            return $this->buildAjaxLink($id, $name, $url, NULL, $ajaxOptions, $htmlOptions);
        }

        if ($type == "ajaxButton") {
            if ($data != NULL)
                $ajaxOptions['data'] = $data;
            $name = $label == NULL ? $id : $label;
            $htmlOptions['class'] = isset($htmlOptions['class']) ? $htmlOptions['class'] . ' btn' : 'btn';
            return $this->buildAjaxLink($id, $name, $url, NULL, $ajaxOptions, $htmlOptions);
        }

        if ($type == "ajaxSubmitButton") {
            if ($data != NULL)
                $ajaxOptions['data'] = NULL;
            $name = $label == NULL ? $id : $label;
            $htmlOptions['class'] = isset($htmlOptions['class']) ? $htmlOptions['class'] . ' btn' : 'btn';
//$htmlOptions['submit'] = 'true';
            return $this->buildAjaxLink($id, $name, $url, NULL, $ajaxOptions, $htmlOptions);
        }

//$ajaxLinkId = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getId() . "_" . $id;
//prepare url
        if ($url == NULL) {
            $url = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getUrl();
        }
//$url[$ajaxLinkId] = '';

        $route = $url[0];
        unset($url[0]);

        $url = yii::app()->getController()->createUrl($route, $url);

        return $url;
    }

    public function createLink($id, $data = array()) {
        $linkType = self::LinkType_AjaxLink;
        if (isset($data['linkType'])) {
            $linkType = $data['linkType'];
        }
        $label = $id;
        if (isset($data['label'])) {
            $label = $data['label'];
        }
        $url = NULL;
        if (isset($data['url'])) {
            $url = $data['url'];
        }
        $ajaxData = NULL;
        if (isset($data['data'])) {
            $ajaxData = $data['data'];
        }
        $htmlOptions = array();
        if (isset($data['htmlOptions'])) {
            $htmlOptions = $data['htmlOptions'];
        }

        return $this->buildLink($id, $label, $linkType, $url, $ajaxData, $htmlOptions);
    }

    protected function getAjaxUrl($data = NULL) {

        if (isset($data['ajaxLink'])) {

            $ajaxLink = $data['ajaxLink'];
//must unset ajaxLink here, otherwise maybe cause some error
            unset($data['ajaxLink']);
            $ajaxLinkId = isset($ajaxLink['id']) ? $ajaxLink['id'] : NULL;
            $ajaxLinkName = isset($ajaxLink['name']) ? $ajaxLink['name'] : NULL;
            $ajaxOptions = isset($ajaxLink['ajaxOptions']) ? $ajaxLink['ajaxOptions'] : NULL;
            $htmlOptions = isset($ajaxLink['htmlOptions']) ? $ajaxLink['htmlOptions'] : NULL;

            if ($ajaxLinkId == NULL)
                $ajaxLinkId = Blyn::app()->getUnicodeId();

            $url = $this->getUrl($data);

            return $this->buildAjaxLink($ajaxLinkId, $ajaxLinkName, $url, NULL, $ajaxOptions, $htmlOptions);
        };

        return NULL;
    }

    public function getLinkFromUrl($data = NULL) {

        $url = $this->getUrl($data);

        $route = $url[0];
        unset($url[0]);

        $url = yii::app()->getController()->createUrl($route, $url);

        return $url;
    }

    public function getUniqueControlId() {
        return 'bln' . $this->count;
    }

}

?>
